#include <n32g45x_usart.h>
#include <usart.h>
#include "log.h"


usart_cache usart1_cache;

usart_cnt usart1_cnt;

void usart_init(void)
{
    usart1_init();
}

void usart1_init(void)
{
    /* Enable GPIO clock */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_AFIO, ENABLE);
    /* Enable USART1 Clock */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE);

    USART_DeInit(USART1);

    NVIC_InitType NVIC_InitStructure;
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

	GPIO_ConfigPinRemap(GPIO_RMP_USART1,ENABLE);
//    GPIO_InitType GPIO_InitStructure;
//    /* Configure USART1 Tx as alternate function push-pull */
//    GPIO_InitStructure.Pin        = GPIO_PIN_9;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
//    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
//    /* Configure USART1 Rx as input floating */
//    GPIO_InitStructure.Pin       = GPIO_PIN_10;
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    GPIO_InitType GPIO_InitStructure;
    /* Configure USART3 Tx as alternate function push-pull */
    GPIO_InitStructure.Pin        = GPIO_PIN_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
    /* Configure USART3 Rx as input floating */
    GPIO_InitStructure.Pin       = GPIO_PIN_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);

    USART_InitType USART_InitStructure;
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
    USART_Init(USART1, &USART_InitStructure);

    /* Enable USART1 Receive and Transmit interrupts */
//    USART_ConfigInt(USART1, USART_INT_RXDNE, ENABLE);
//    USART_ConfigInt(USART1, USART_INT_IDLEF, ENABLE);
//    USART_ConfigInt(USART1, USART_INT_TXDE, ENABLE);

    /* Enable the USART1*/
    USART_Enable(USART1, ENABLE);
}

HAL_StatusTypeDef HAL_UART_Transmit(USART_Module* USARTx, uint8_t* data, uint32_t len, uint32_t time_out)
{
    uint32_t cnt = 0;
    usart1_cnt.cnt = 0;
//	SysTick_Delay_Ms( 5 );
    while((cnt<len)&&(usart1_cnt.cnt <= time_out))
    {
        USART_SendData(USARTx, data[cnt]);
        /* Loop until USARTy DAT register is empty */
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET)
        {
        }

        cnt+=1;
    }
    if(usart1_cnt.cnt > time_out)
        return HAL_TIMEOUT;
    else
        return HAL_OK;
}

HAL_StatusTypeDef HAL_UART_Receive(USART_Module* USARTx, uint8_t* data, uint32_t len, uint32_t time_out)
{

    uint32_t cnt = 0;
    usart1_cnt.cnt = 0;
//	SysTick_Delay_Ms( 5 );
    while((cnt<len)&&(usart1_cnt.cnt <= time_out))
    {
        /* Loop until the USARTz Receive Data Register is not empty */
        while ((USART_GetFlagStatus(USARTx, USART_FLAG_RXDNE) == RESET)&&(usart1_cnt.cnt <= time_out))
        {
        }
        /* Store the received byte in RxBuffer */
        data[cnt] = (USART_ReceiveData(USARTx));
        cnt+=1;
        USART_GetFlagStatus(USARTx, USART_FLAG_RXDNE);

    }
    if(usart1_cnt.cnt > time_out)
        return HAL_TIMEOUT;
    else
        return HAL_OK;

}

